/*
 * Unidata Platform
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 *
 * Commercial License
 * This version of Unidata Platform is licensed commercially and is the appropriate option for the vast majority of use cases.
 *
 * Please see the Unidata Licensing page at: https://unidata-platform.com/license/
 * For clarification or additional options, please contact: info@unidata-platform.com
 * -------
 * Disclaimer:
 * -------
 * THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT ANY WARRANTIES, CONDITIONS AND
 * REPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
 * IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,
 * FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE AND
 * THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.
 */
/**
 *
 */
package org.unidata.mdm.rest.v1.meta.converter;

import java.util.List;
import java.util.stream.Collectors;

import org.unidata.mdm.meta.type.model.attributes.AttributeGroup;
import org.unidata.mdm.meta.type.model.attributes.CodeMetaModelAttribute;
import org.unidata.mdm.meta.type.model.entities.LookupEntity;
import org.unidata.mdm.rest.core.converter.CustomPropertiesConverter;
import org.unidata.mdm.rest.system.ro.SimpleDataType;
import org.unidata.mdm.rest.v1.meta.converter.entities.AbstractEntityDefinitionConverter;
import org.unidata.mdm.rest.v1.meta.ro.attributes.CodeAttributeRO;
import org.unidata.mdm.rest.v1.meta.ro.entities.LookupEntityRO;
import org.unidata.mdm.rest.v1.meta.ro.groups.GroupsRO;


/**
 *
 *
 * @author Mikhail Mikhailov
 */
public class LookupEntityDefToLookupEntityDefinitionConverter extends AbstractEntityDefinitionConverter {

	/**
	 * Instantiation disabled.
	 */
	private LookupEntityDefToLookupEntityDefinitionConverter() {
		super();
	}

	/**
	 * Converts lookup entity from internal to REST.
	 *
	 * @param source
	 *            the source
	 * @return REST
	 */
	public static LookupEntityRO toLookupEntityRO(LookupEntity source) {

		LookupEntityRO target = new LookupEntityRO();

		target.setDashboardVisible(source.isDashboardVisible());
		target.setGroupName(source.getGroupName());

		convertAttributeGroups(source.getAttributeGroups(), target.getAttributeGroups());
		toAbstractEntityData(source, target);
		copyCodeAttribute(source.getCodeAttribute(), target.getCodeAttribute(), source.getName());
		target.setCustomProperties(CustomPropertiesConverter.to(source.getCustomProperties()));

		target.getSimpleAttributes().addAll(toSimpleAttrs(source.getSimpleAttribute(), source.getName()));
		target.getArrayAttributes().addAll(toArrayAttrs(source.getArrayAttribute(), source.getName()));

		for (CodeMetaModelAttribute codeAttributeDef : source.getAliasCodeAttributes()) {
			CodeAttributeRO codeAttributeDefinition = new CodeAttributeRO();
			copyCodeAttribute(codeAttributeDef, codeAttributeDefinition, source.getName());
			target.getAliasCodeAttributes().add(codeAttributeDefinition);
		}
		source.getAliasCodeAttributes().stream().map(f -> new CodeAttributeRO()).collect(Collectors.toList());

		target.setValidityPeriod(PeriodBoundaryConverter.to(source.getValidityPeriod()));
		target.setMergeSettings(MergeSettingsConverter.to(source.getMergeSettings()));
		target.setExternalIdGenerationStrategy(
				ExternalIdGenerationStrategyConverter.to(source.getExternalIdGenerationStrategy()));


		return target;
	}


	/**
	 * Convert Model object to Request object.
	 *
	 * @param sourceAttributeGroups
	 *            - will be used for filling
	 * @param targetAttributeGroups
	 *            - will be filled
	 */
	private static void convertAttributeGroups(List<AttributeGroup> sourceAttributeGroups,
			List<GroupsRO> targetAttributeGroups) {
		for (AttributeGroup attributeGroup : sourceAttributeGroups) {
			GroupsRO attributeGroupRo = new GroupsRO()
			        .withRow(attributeGroup.getRow())
					.withTitle(attributeGroup.getTitle())
					.withColumn(attributeGroup.getColumn())
					.withAttributes(attributeGroup.getAttributes());

			attributeGroupRo.setCustomProperties(CustomPropertiesConverter.to(attributeGroup.getCustomProperties()));
            attributeGroupRo.setDefaultGroup(attributeGroup.isDefaultGroup());

            targetAttributeGroups.add(attributeGroupRo);
		}
	}

	/**
	 * Copy code attribute.
	 *
	 * @param source            the source
	 * @param target            target
	 * @param securityPath the security path
	 */
	private static void copyCodeAttribute(CodeMetaModelAttribute source, CodeAttributeRO target,
										  String securityPath) {

		toAbstractAttributeData(source, target, securityPath);

		target.setNullable(source.isNullable());
		target.setUnique(source.isUnique());
		target.setSearchable(source.isSearchable());
		target.setDisplayable(source.isDisplayable());
		target.setMainDisplayable(source.isMainDisplayable());
		target.setExternalIdGenerationStrategy(ExternalIdGenerationStrategyConverter.to(source.getValueGenerationStrategy()));

		if (source.getSimpleDataType() != null) {
			target.setSimpleDataType(
					source.getSimpleDataType() != null ? SimpleDataType.fromValue(source.getSimpleDataType().name())
							: null);
		}
	}
}
